#!/usr/bin/python

""" Measure cpu usage, disk io, network io of pig
"""

import os, subprocess, time
import re

def digit_2_str(value):
    pattern = re.compile(r'(?<=\d)(?=(\d\d\d)+(?!\d))')
    return pattern.sub(',', str(value))

def get_curr_time_str():
    return time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())

def get_network_bytes():
    recv_bytes = 0;
    send_bytes = 0;
    
    f = open('/proc/net/dev')
    lines = f.read().split('\n')
    
    for line in lines:
        curr_line = line.strip()
        
        if curr_line.startswith('eth'):
            i = curr_line.find(':')
            curr_line = curr_line[i + 1 : ]
            items = curr_line.split()
            recv_bytes = int(items[0])
            send_bytes = int(items[8])
            
    f.close()
    
    return recv_bytes, send_bytes


def get_cpu_jiffies():
    idle_jiffies = 0
    total_jiffies = 0
    f = open('/proc/stat')
    line = f.read().split('\n')[0]
    items = line.split()
    
    for item in items[1:]:
        total_jiffies += int(item)
    
    idle_jiffies = int(items[4])
    
    f.close()
    return idle_jiffies, total_jiffies

def get_disk_io():
    read_sector_count = 0
    read_time = 0
    write_sector_count = 0
    write_time = 0

    f = open('/proc/diskstats')
    lines = f.read().split('\n')
    for line in lines:
        if 'xvda1' in line:
            items = line.split()
            read_sector_count = int(items[5])
            read_time = int(items[6])
            write_sector_count = int(items[9])
            write_time = int(items[10])
    f.close()
    return read_sector_count, read_time, write_sector_count, write_time
            

if __name__ == '__main__':
    pig_command = '/root/software/apache-cassandra-0.7.4-src/contrib/pig/bin/pig_cassandra_measure'
    pig_script = '/root/pigappscale/guestbook_countAuthor.pig'

    # record system informations before running
    time_old = time.time()
    recv_bytes_old, send_bytes_old = get_network_bytes()
    idle_jiffies_old, total_jiffies_old = get_cpu_jiffies()
    read_sector_count_old, read_time_old, write_sector_count_old, write_time_old = get_disk_io()

    # run pig_cassandra
    command = [pig_command, pig_script]
    #command = ['/root/test_code/pig_bear/measure1/bear_pig_cassandra', '-x', 'local', '/root/test_code/pig_bear/measure1/guestbook.pig']
    p = subprocess.Popen(command)
    p.wait()
    
    # record system informations after running
    time_curr = time.time()
    recv_bytes_curr, send_bytes_curr = get_network_bytes()
    idle_jiffies_curr, total_jiffies_curr = get_cpu_jiffies()
    read_sector_count_curr, read_time_curr, write_sector_count_curr, write_time_curr = get_disk_io()
    
    # calculate results
    total_seconds = time_curr - time_old
    total_network_recv = recv_bytes_curr - recv_bytes_old
    total_network_send = send_bytes_curr - send_bytes_old
    total_cpu_jiffies = total_jiffies_curr - total_jiffies_old
    total_cpu_idle_jiffies = idle_jiffies_curr - idle_jiffies_old
    total_disk_read_sector = read_sector_count_curr - read_sector_count_old
    total_disk_read_time = read_time_curr - read_time_old
    total_disk_write_sector = write_sector_count_curr - write_sector_count_old
    total_disk_write_time = write_time_curr - write_time_old
    
    # display results
    print 'done at ' + get_curr_time_str()
    print '========================================================================='
    print 'Command :   ' + ' '.join(command)
    print '========================================================================='
    print 'Total Time: ' + str(total_seconds) + ' seconds'
    print 'CPU: '
    print '     Used : ' + digit_2_str(total_cpu_jiffies - total_cpu_idle_jiffies) + ' jiffies (' + str(round((total_cpu_jiffies - total_cpu_idle_jiffies) * 100.0 / total_cpu_jiffies, 2)) + ' %)'
    print 'Disk:'
    print '     Read : ' + digit_2_str(total_disk_read_sector) + ' Sectors in ' + digit_2_str(total_disk_read_time) + ' ms'
    print '     Write: ' + digit_2_str(total_disk_write_sector) + ' Sectors in ' + digit_2_str(total_disk_write_time) + ' ms'
    print 'Network:'
    print '     Recv : ' + digit_2_str(total_network_recv) + ' Bytes, ' + digit_2_str(int(round(total_network_recv / total_seconds))) + ' Bps'
    print '     Send : ' + digit_2_str(total_network_send) + ' Bytes, ' + digit_2_str(int(round(total_network_send / total_seconds))) + ' Bps'
    print '========================================================================='
